package com.hyt.it.ogt.kq.service.bm.pay;

import com.google.common.base.Charsets;
import com.hyt.it.ogt.kq.service.bm.model.dto.pay.YeepayJsonConfigDto;
import com.yeepay.yop.sdk.auth.credentials.PKICredentialsItem;
import com.yeepay.yop.sdk.auth.signer.process.YopSignProcessorFactory;
import com.yeepay.yop.sdk.security.CertTypeEnum;
import com.yeepay.yop.sdk.security.DigestAlgEnum;
import com.yeepay.yop.sdk.security.rsa.RSA;
import com.yeepay.yop.sdk.security.rsa.RSAKeyUtils;
import com.yeepay.yop.sdk.utils.Encodes;
import com.yeepay.yop.sdk.utils.Sm2Utils;

import java.security.PrivateKey;

public class YeepaySign {

    public static String RSA_SUFFIX = "$SHA256";

    public static String SM_SUFFIX = "$SM3";

    // 获取请求收银台的sign
    private static String signature(String plainText, PrivateKey privateKey) {
        CertTypeEnum certType = resolveCertType(privateKey);
        return YopSignProcessorFactory.getSignProcessor(certType.name()).sign(plainText, new PKICredentialsItem(privateKey, null, certType));
    }

    private static CertTypeEnum resolveCertType(PrivateKey privateKey) {
        switch (privateKey.getAlgorithm()) {
            case "RSA":
                return CertTypeEnum.RSA2048;
            case "EC":
                return CertTypeEnum.SM2;
            default:
                throw new RuntimeException("sign algorithm(" + privateKey.getAlgorithm() + ") not supported");
        }
    }

    /**
     * 获取易宝请求标准收银台生成的sign
     *
     * @param content
     * @param yeepaConfig
     * @return
     */
    public static String getSign(String content, YeepayJsonConfigDto yeepaConfig) {

        String priKey = yeepaConfig.getIsv_private_key().getValue();
        String encrptType = yeepaConfig.getIsv_private_key().getCert_type();
        PrivateKey privateKey = null;
        String signSuffix = null;

        switch (encrptType.toUpperCase()) {
            case "SM2":
                privateKey = Sm2Utils.string2PrivateKey(priKey);
                signSuffix = SM_SUFFIX;
                break;
            case "RSA2048":
                privateKey = RSAKeyUtils.string2PrivateKey(priKey);
                signSuffix = RSA_SUFFIX;
                break;
            default:
                break;
        }
        return signature(content, privateKey) + signSuffix;
    }

    /**
     * rsa生成sign
     *
     * @param plainText
     * @param priKey
     * @return
     */
    public static String getRsaSign(String plainText, String priKey) {
        PrivateKey privateKey = RSAKeyUtils.string2PrivateKey(priKey);

        byte[] data = plainText.getBytes(Charsets.UTF_8);
        byte[] signByte = RSA.sign(data, privateKey, DigestAlgEnum.SHA256);
        String signToBase64 = Encodes.encodeUrlSafeBase64(signByte);

        String sign = signToBase64 + RSA_SUFFIX;
        return sign;
    }


}
